package com.kitty.game.mail.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.ServerService;
import com.kitty.game.artifact.ArtifactService;
import com.kitty.game.base.service.BagService;
import com.kitty.game.enter.TitleInfo;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.equip.service.FabaoService;
import com.kitty.game.item.service.PointItemService;
import com.kitty.game.mail.message.MailInfo;
import com.kitty.game.mail.message.RespMailBoxRefresh;
import com.kitty.game.mail.model.Mail;
import com.kitty.game.onlinemall.service.MallService;
import com.kitty.game.pet.PetDataPool;
import com.kitty.game.pet.bean.PetObject;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.PayService;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.Const;
import com.kitty.game.utils.TimeUtil;
import com.kitty.listener.EventType;
import com.kitty.listener.annotation.EventHandler;
import com.kitty.listener.event.LoginEvent;
import com.kitty.common.model.Reason;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.task.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;


@Service
@Slf4j
public class MailService {

    @Autowired
    Dao dao;
    @Autowired
    PetService petService;
    @Autowired
    MallService mallService;
    @Autowired
    ArtifactService artifactService;
    @Autowired
    RoleService roleService;
    @Autowired
    BagService bagService;
    @Autowired
    EquipService equipService;

    @Resource
    PayService payService;

    @Resource
    FabaoService fabaoService;

    /**
     * 登录事件
     */
    @EventHandler(EventType.LOGIN)
    public void handleLoginEvent(LoginEvent loginEvent) {
        Role role = loginEvent.getRole();

       // delMail(role);
        /**加载邮件*/

        SpringUtils.getBean(ServerService.class).getScheduledExecutorService().schedule(new Runnable() {
            @Override
            public void run() {
                loadMails(role);
            }
        }, 3, TimeUnit.SECONDS);

        role.save();

    }

    public void delMail(Role role) {
        List<Mail> mails = getMails(role);
//        logger.error("未删除邮件数量=={}",mails.size());
        if (mails != null) {
            long now = System.currentTimeMillis();
            long expireTime = TimeUtil.ONE_HOUR;//没有附件的邮件，一个小时就删除
            List<Mail> removeList = new ArrayList<>();
            for (Mail mail : mails) {
                if (now - mail.getCreateTime() >= expireTime
                        && (mail.getDatas() == null || mail.getDatas().size() == 0) || mail.getStatus() >= 3) {
                    removeList.add(mail);
                }
            }
            for (Mail mail : removeList) {
                role.getMailBox().getAllMail().remove(mail.getId());
                log.warn("删除邮件,roleid:{},title:{},content:{}", role.getUid(), mail.getTitle(), mail.getMailMsg());
            }
        }
    }

    /**
     * 返回邮件附件包含物品文本
     */
    private String getMailItemString(ArrayList<NutMap> maps) {
        StringBuilder stringBuilder = new StringBuilder();
        if (maps != null) {
            for (NutMap nutMap : maps) {
                stringBuilder.append(nutMap.getString("data"));
            }
        }
        return stringBuilder.toString();
    }

    /**
     * 发送所有邮件封包
     */
    private void sendMailPackge(Role role, List<Mail> mails) {
        for (Mail mail : mails) {
            if (mail.getStatus() >= 3) {
                continue;
            }
            flushMail(role, mail);
//            logger.error("邮件时间=={}=={}=={}",DateUtils.formatDate(new Date(mail.getCreateTime())),DateUtils.formatDate(new Date(mail.getExpireTme())),mail.getStatus());
//            MailInfo mailInfo = new MailInfo();
//            mailInfo.setStartTime((int) ((mail.getCreateTime()+8*TimeUtil.ONE_HOUR) / 1000));
//            mailInfo.setEndTime((int) ((System.currentTimeMillis()+TimeUtil.ONE_DAY) / 1000));
//            mailInfo.setMailTitle(mail.getTitle());
//            mailInfo.setMailId(mail.getId());
//            mailInfo.setMailMsg(mail.getMailMsg());
//            mailInfo.setStauts(mail.getStatus());
//            mailInfo.setGiftItem(getMailItemString(mail.getDatas()));
//            ArrayList<MailInfo> list = new ArrayList<>();
//            list.add(mailInfo);
//            RespMailBoxRefresh respMailBoxRefresh = new RespMailBoxRefresh();
//            respMailBoxRefresh.setList(list);
//            MessagePusher.pushMessage(role, respMailBoxRefresh);
        }

    }

    /**
     * 登录获取所有邮件
     */
    public void loadMails(Role role) {
        sendMailPackge(role, getMails(role));
    }

    /**
     * 取邮件列表
     */
    private List<Mail> getMails(Role role) {
        return new ArrayList<>(role.getMailBox().getAllMail().values());
    }

    /**
     * 添加并刷新邮件
     */
    public void sendNewMail(Role role, Mail mail) {
        if (role == null || mail == null) {
            try {
                throw new Exception();
            } catch (Exception e) {
                log.error("发送邮件失败", e);
            }
            return;
        }

        role.getMailBox().addMail(mail);
        role.save();

        if (SpringUtils.getRoleService().isOnline(role)) {
            List<Mail> mails = getMails(role);
            sendMailPackge(role, mails);
        }
    }

    /**
     * 通过uid添加并刷新邮件
     */
    public void sendNewMailByUid(long uid, Mail mail) {
        Role role = SpringUtils.getPlayerService().getPlayerBy(uid);
        if (role == null) {
            /**找不到对应uid的角色*/
            log.error("发邮件时找不到对应的角色, uid:{}", uid);
            return;
        }

        if (SpringUtils.getRoleService().isOnline(role)) {
            ThreadLocalUtil.addLocalTask(role, () -> {
                role.getMailBox().addMail(mail);
                role.save();
                List<Mail> mails = getMails(role);
                sendMailPackge(role, mails);
            });
        } else {
            role.getMailBox().addMail(mail);
            role.save();
        }
    }

    /**
     * 删除邮件
     */
    public void removeMail(Role role, String mailId) {
        Mail mail = role.getMailBox().modifyMail(mailId, (short) 3);
        if (mail != null) {
            flushMail(role, mail);
        }
        delMail(role);
    }

    /**
     * 打开邮件
     * 如果是未读邮件
     * 把该邮件置为已读并发送刷新封包
     */
    public void openMail(Role role, String mailId) {
        Mail mail = role.getMailBox().getMail(mailId);
        if (mail != null && mail.getStatus() == 0) {//如果邮件是未打开状态才把状态设置1 避免无限领取
            mail.setStatus((short) 1);
            flushMail(role, mail);
        }
    }

    /**
     * 刷新邮件
     */
    private void flushMail(Role role, Mail mail) {
        ArrayList<MailInfo> list = new ArrayList<>();
        long now = System.currentTimeMillis();
        MailInfo mailInfo = new MailInfo();
        mailInfo.setStartTime((int) ((mail.getCreateTime()) / 1000));
        mailInfo.setEndTime((int) (mail.getExpireTme() / 1000));
        mailInfo.setMailTitle(mail.getTitle());
        mailInfo.setMailId(mail.getId());
        mailInfo.setMailMsg(mail.getMailMsg());
        mailInfo.setStauts(mail.getStatus());
        mailInfo.setGiftItem(getMailItemString(mail.getDatas()));
        list.add(mailInfo);
        RespMailBoxRefresh respMailBoxRefresh = new RespMailBoxRefresh();
        respMailBoxRefresh.setList(list);
        MessagePusher.pushMessage(role, respMailBoxRefresh);
    }

    /**
     * 领取邮件附件
     * 判断该邮件是否有未领取的物品
     */
    public void getMailItem(Role role, String mailId) {
        Mail mail = getMail(role, mailId);
        if(mail == null || mail.getStatus() >= 2){
            return;
        }
        ArrayList<NutMap> maps = mail.getDatas();
        for (NutMap nutMap : maps) {
            int type = nutMap.getInt("type",0);
            String data = nutMap.get("data").toString().replaceAll("#I","");
            String showType = data.split("\\|")[0];
            String showName = data.split("\\|")[1].split("#r")[0];
            //道行|道行#r1,064
            String value = data.split("\\|")[1].split("#r")[1].replace(",","");
            int number = Integer.parseInt(value);

            if(type == Const.rewardWupin){
                short pos = bagService.getPos(role, false);
                if (pos <= 0) {
                    MessagePusher.pushMessage(role, new RespNotifyMiscEx("背包已满"));
                    return;
                }
                equipService.addMall(showName, true, role, number);
            }else if(type == Const.rewardJifen){
                roleService.addRechargeScore(role, number);
            }else if(type == Const.rewardqimenJifen){
                roleService.addmijingjifen(role, number);
            }else if(type == Const.rewardhaoxinzhi){
                roleService.addhaoxianzhi(role, number);
            }else if(type == Const.rewardTao){
                roleService.addTao(role, number);
            }else if(type == Const.rewardChongwu){
                String petName = nutMap.getString("petName","松鼠");
                if (SpringUtils.getPetService().isEquippedFull(role,petName)) {
                    MessagePusher.pushMessage(role, new RespMsg("当前宠物包裹已满，请整理后再来吧。"));
                    return;
                }
                if (!Strings.isEmpty(petName)) {
                    PetObject petObject = PetDataPool.getPetObject(petName);
                    Pet pet = petService.addPet(petObject, role, false);
                    petService.loadPet(role, pet);
                    RespNotifyMiscEx respNotifyMiscEx = new RespNotifyMiscEx();
                    respNotifyMiscEx.setMsg("你获得了一只#R" + petObject.getName() + "#n。");
                    respNotifyMiscEx.setTime(new Long(System.currentTimeMillis() / 1000).intValue());
                    MessagePusher.pushMessage(role, respNotifyMiscEx);
                }
            }else if(type == Const.rewardShoushi){
                String name = showName.split("\\(")[0];
                if("低级随机".equals(name)){
                    int[] levels = {20, 35, 50,60,70};
                    int index = ThreadLocalRandom.current().nextInt(levels.length);
                    RoleEquip roleEquip = equipService.getRandomJewelry(levels[index], role);
                    if(roleEquip== null){
                        return;
                    }
                    equipService.refreshRoleEquip(role,roleEquip);
                    MessagePusher.pushMessage(role, new RespNotifyMiscEx("你获得了一件#R" + roleEquip.getName() + "#n。"));
                }else{
                    SpringUtils.getEquipService().getJewelryNew(role, name, 1, showName, false);
                }
            }else if(type ==Const.rewardFabao){
                int polar = Integer.parseInt(nutMap.getString("polar","1"));
                SpringUtils.getBean(FabaoService.class).getArtifact(role, showName, polar, number);
            }else if(type == Const.rewardJinyuanbao){
                roleService.addGold(role, number, Reason.MAIL_ITEM);
                roleService.updateRoleGoldAndSiver(role);
            }else if(type == Const.rewardYinyuanbao){
                roleService.addSiver(role, number, Reason.FETCH_MAIL);
            }else if(type ==  Const.rewardGuiqi){
                roleService.addGuiQi(role,number,true);
            }else if(type == Const.rewardYinde){
                roleService.addYinde(role,number,true);
            }else if(type == Const.rewardWuhun){
                roleService.addWuling(role,number,false);
            }else if(type == Const.rewardLuoshu){
                roleService.addluoshuExp(role, number);
            }else if("魂器".equals(type)){

            }else if("魂窍".equals(type)){

            }else if(type == Const.rewardJingYan){
                roleService.addExp(role, number, role.getLevel(), 0);
            }else if("mailEquip".equals(type)){

            }else if (type == Const.mailPointItem) {
                String name = nutMap.getString("name");
                int count = nutMap.getInt("value", 0);

                if (name.equals(Const.CHONG_FEN_SAN_ITEM_NAME)) {
                    SpringUtils.getBean(PointItemService.class).addChongFengSan(role, count);
                } else if (name.equals(Const.ZI_QI_HONG_MENG_ITEM_NAME)) {
                    SpringUtils.getBean(PointItemService.class).addZiQiHongMeng(role, count);
                }
            }
        }
        mail.setStatus((short) 2);
        mail.setUpdateTime(System.currentTimeMillis());
        flushMail(role, mail);
    }
    // 一键领取
    public void getAllMailItem(Role role) {
        Map<String, Mail> allMail = role.getMailBox().getAllMail();
        List<String> unGetMails =  new ArrayList<>();
        for (Map.Entry<String, Mail> entry : allMail.entrySet()) {
            Mail mail = getMail(role, entry.getKey());
            if (mail != null && mail.getStatus() < 2)
                unGetMails.add(entry.getKey());
        }
        // 一键领取
        for (String mailId : unGetMails) {
            getMailItem(role, mailId);
        }
    }

    /**
     * 邮件ID取邮件信息 todo 需要判断邮件是否被更新
     */
    private Mail getMail(Role role, String mailId) {
        return role.getMailBox().getMail(mailId);
    }

    /**
     * 单笔赠送
     * 五千送太极,3000变异,2000,筋斗云,4000,墨麒麟,10000送朱雀
     *
     * @param role
     * @param session
     */
    public void sendMail(Role role, int rmb, IoSession session) {
    }

    public void buchang(Role role, String name, int value) {
        Mail mail = SpringUtils.getMailService().createMail("积分礼包", "积分礼包", 30 * TimeUtil.ONE_DAY);
        if (name.equals("积分")) {
            mail.getDatas().add(new NutMap().setv("data", "#I积分|积分#r" + value + "#I").setv("type", Const.rewardJifen).setv("value", value));
        } else if (name.equals("奇门积分")) {
            mail.getDatas().add(new NutMap().setv("data", "#I奇门积分|奇门积分#r" + value + "#I").setv("type", Const.rewardqimenJifen).setv("value", value));
        } else if (name.equals("好心值")) {
            mail.getDatas().add(new NutMap().setv("data", "#I好心值|好心值#r" + value + "#I").setv("type", Const.rewardhaoxinzhi).setv("value", value));
        } else if (name.equals("银元宝")) {
            mail.getDatas().add(new NutMap().setv("data", "#I银元宝|银元宝#r" + value + "#I").setv("type", Const.rewardYinyuanbao).setv("value", value));
        } else if (name.equals("金元宝")) {
            mail.getDatas().add(new NutMap().setv("data", "#I金元宝|金元宝#r" + value + "#I").setv("type", Const.rewardJinyuanbao).setv("value", value));
        } else if (name.equals("金钱")) {
            mail.getDatas().add(new NutMap().setv("data", "#I金钱|金钱#r" + value + "#I").setv("type", Const.rewardYinyuanbao).setv("value", value));
        } else {
            if (PetDataPool.getPetObject(name) != null) {
                ArrayList<NutMap> maps = new ArrayList<>();
                if (PetDataPool.epic_pets.get(name) != null) {
                    maps.add(new NutMap().setv("data", "#I宠物|" + name + "(神兽)#r" + value + "#I").setv("type", Const.rewardChongwu).setv("petName", name).setv("value", value));
                } else if (PetDataPool.variation_pets.get(name) != null) {
                    maps.add(new NutMap().setv("data", "#I宠物|" + name + "(变异)#r" + value + "#I").setv("type", Const.rewardChongwu).setv("petName", name).setv("value", value));
                } else if (PetDataPool.jingguai_pets.get(name) != null) {
                    maps.add(new NutMap().setv("data", "#I宠物|" + name + "(精怪)#r" + value + "#I").setv("type", Const.rewardChongwu).setv("petName", name).setv("value", value));
                } else {
                    maps.add(new NutMap().setv("data", "#I宠物|" + name + "#r" + value + "#I").setv("type", Const.rewardChongwu).setv("petName", name).setv("value", value));
                }
                mail.getDatas().addAll(maps);
            } else {
                ArrayList<NutMap> maps = new ArrayList<>();
                maps.add(new NutMap().setv("data", "#I物品|" + name + "#r" + value + "#I").setv("type", Const.rewardWupin).setv("petName", name).setv("value", value));
                mail.getDatas().addAll(maps);
            }
        }
        sendNewMail(role, mail);
    }
    /*累计*/
    public void sendLeijiMail(Role role) {
        int totalCharge = role.getTotalCharge();
        int num = totalCharge / 10000;
        int last = totalCharge % 10000;
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        for (Integer integer : role.getExtendBox().getTotalContent()) {
            hashMap.merge(integer, 1, Integer::sum);
        }
        log.error("累计数据=={}=={}", Json.toJson(role.getExtendBox().getTotalContent(), JsonFormat.compact()), Json.toJson(hashMap, JsonFormat.compact()));
        ArrayList<Integer> arrayList = new ArrayList<>();
        arrayList.add(50);
        arrayList.add(100);
        arrayList.add(200);
        arrayList.add(500);
        arrayList.add(1000);
//        arrayList.add(1000);
//        arrayList.add(2000);
//        arrayList.add(3000);
//        arrayList.add(5000);
//        arrayList.add(8000);
//        arrayList.add(10000);
//        arrayList.add(15000);
        for (Integer integer : arrayList) {
            Integer already = hashMap.get(integer);
            if (already == null) {
                already = 0;
            }
            int curr = num;
            if (last >= integer) {
                curr = num + 1;
            }
            if (already >= curr) {
                continue;
            }
            role.getExtendBox().getTotalContent().add(integer);
        }
        role.save();
    }

    public Mail createMail(String title, String content, long expireTimeMillis) {
        long now = System.currentTimeMillis();
        Mail mail = new Mail();
        mail.setStatus((short) 0);
        mail.setCreateTime(now);
        mail.setUpdateTime(now);
        mail.setExpireTme(now + expireTimeMillis);
        mail.setTitle(title);
        mail.setId(R.UU32().toUpperCase());
        mail.setMailMsg(content);
        ArrayList<NutMap> maps = new ArrayList<>();
        mail.setDatas(maps);
        return mail;
    }

    public void title(Role role, String title) {
        TitleInfo titleInfo = new TitleInfo();
        titleInfo.setType(title);
        titleInfo.setTitle(title);
        SpringUtils.getRoleService().addTitle(role, titleInfo);
    }
}
